import { h, init } from 'snabbdom'
import classModule from 'snabbdom/modules/class'
import propsModule from 'snabbdom/modules/props'
import styleModule from 'snabbdom/modules/style'
import eventListenersModule from 'snabbdom/modules/eventlisteners'
import { Data } from './utils/data'

const appData = {
  nextRank: Data.length + 1,
  data: [...Data],
  margin: 10,  //上下两列表间隔
  sort: 'rank',  //排序方式
  totalHeight: 0  //列表总高度
}

let patch = init([
  classModule,
  propsModule,
  styleModule,
  eventListenersModule
])

let app = document.querySelector('#app')


let oldApp = null




function view(data) {

  let vnode = h('div#app', [
    h('h1', 'Top 10 movies'),
    h('div', [
      h('a.btn.add',{ on: { click: addList }}, 'Add'),
      'Sort by: ',
      h('span.btn-group', [
        h('a.btn.rank', { 'class': { active: appData.sort === 'rank' }, on: { click: [changeSort, 'rank'] }},'Rank'),
        h('a.btn.title', { 'class': { active: appData.sort === 'title' }, on: { click: [changeSort, 'title'] }},'Title'),
        h('a.btn.desc', { 'class': { active: appData.sort === 'desc' }, on: { click: [changeSort, 'desc'] }},'Description')
      ]),
      h('div.list', data.map(listView))
    ])
  ])

  return vnode
}

function listView(movie, index) {
  return h(
    'div.row', 
    {
      key: movie.rank,
      style: {
        opacity: '0', 
        transform: 'translate(-200px)',
        delayed: { transform: 'translateY(' + movie.offset + 'px)', opacity: '1' },
        remove: { opacity: '0', transform: 'translateY(' + movie.offset + 'px) translateX(200px)' } 
      },
      hook: {
        insert: vnode => {
          movie.elmHeight = vnode.elm.offsetHeight
          let data = [...appData.data]
          data = data.map(item => {
            if(item.rank === movie.rank) return {...item, elmHeight: vnode.elm.offsetHeight }
            return item
          })
          appData.data = data
        }
      }
    },
    [
      h('div', { style: { fontWeight: 'bold' } }, movie.rank), 
      h('div', movie.title), 
      h('div', movie.desc), 
      h('div.btn.rm-btn', { 
        on: { 
          click: [remove, index] 
        } 
      }, 'x')
    ]
  )
}
//新增列表
function addList(data) {
  let { nextRank } = appData
  let newMovie = appData.data[Math.floor(Math.random()*10)]
  nextRank = nextRank + 1
  appData.data = [{...newMovie, rank: nextRank }].concat(appData.data)
  appData.nextRank = nextRank
  randerView()
}
//重新排列
function changeSort(type) {
  let data = [...appData.data]
  appData.data = data.sort((a,b) => {
    return a[type] > b[type] ? 1 : (a[type] < b[type] ? -1 : 0)
  })
  appData.sort = type
  randerView()
}
//列表删除
function remove(index) {
  appData.data.splice(index, 1)
  randerView()
}
//重绘
function randerView() {
  let { margin } = appData
  let newData = [...appData.data];
  newData = newData.reduce(function (acc, cur) {
    const last = acc[acc.length - 1];
    const newM = { ...cur };
    // 计算offset
    newM.offset = last ? (last.offset + last.elmHeight + margin) : margin;
    return acc.concat(newM);
  }, []);

  appData.data = newData
  rander(view(appData.data))
}

//绘制
function rander(newVnode) {
  oldApp = patch(oldApp, newVnode)
}

//初次渲染
function initView() {
  oldApp = patch(app, view(appData.data))
  //计算height后重新渲染
  randerView()
}


initView()
